home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp95 / freyja_t.z / freyja_t / term.c < prev    next >
C/C++ Source or Header  |  1992-04-14  |  14KB  |  866 lines

  1. /* TERM.C -- Terminal Interface Routines
  2.  
  3.     Written March 1991 by Craig A. Finseth
  4.     Copyright 1991 by Craig A. Finseth
  5. */
  6.  
  7. #include "freyja.h"
  8.  
  9. #if defined(UNIX)
  10. #undef TRUE
  11. #undef FALSE
  12. #undef CR
  13. #undef NL
  14. #undef BS
  15. #include <curses.h>
  16.  
  17. #if defined(UNIXV)
  18. static int savemodes;
  19. #else    /* assume Berkeley sockets */
  20. #endif
  21. #endif
  22.  
  23. #if defined(UNIX)
  24. #if defined(UNIXV)
  25. #else    /* assume Berkeley sockets */
  26. #if defined(SUNOS3)
  27. #define KERNEL        1    /* Sun repeats the declaration of struct tm */
  28. #endif                /* in this file, so we work around it */
  29. #include <sys/time.h>
  30. #if defined(SUNOS3)
  31. #undef KERNEL
  32. #endif
  33. #include <sys/ioctl.h>
  34. #define RFDSIZE        32    /* in bits */
  35. static struct sgttyb savtty;
  36. #endif
  37. #endif
  38.  
  39. static int gotchar;    /* buffered character */
  40.  
  41. static int offset;    /* horizontal offset */
  42.  
  43. static int row;        /* current row and column */
  44. static int col;
  45.  
  46. static char printbuf[SMALLBUFFSIZE];  /* for TPrintChar */
  47.  
  48. static char outbuf[128]; /* output buffer */
  49. static char *outptr;
  50.  
  51. static int width;
  52. static int height;
  53.  
  54. #if defined(MSDOS)
  55. #define NORMAL        7    /* normal video */
  56. #define REVERSE        112    /* reverse video */
  57. char t_attrib;
  58.  
  59. static char huge *scrnbase;
  60. static char huge *scrnptr;
  61.  
  62. static int line_offsets[] = {
  63.     0, 160, 320, 480, 640, 800,
  64.     960, 1120, 1280, 1440, 1600,
  65.     1760, 1920, 2080, 2240, 2400,
  66.     2560, 2720, 2880, 3040, 3200,
  67.     3360, 3520, 3680, 3840, 4000 };
  68. #endif
  69.  
  70. void T_RawChar();    /* char c */
  71. void T_RawFlush();    /* void */
  72. void T_RawStr();    /* char *str */
  73.  
  74. /* ------------------------------------------------------------ */
  75.  
  76. FLAG
  77. TInit()
  78.     {
  79. #if defined(UNIX)
  80. #if !defined(UNIXV)
  81.     struct sgttyb tty;
  82. #endif
  83. #endif
  84.     gotchar = -1;
  85.     offset = 0;
  86.     row = 0;
  87.     col = 0;
  88.     outptr = outbuf;
  89.     width = 80;
  90.     height = 24;
  91.  
  92. #if defined(MSDOS)
  93.     if (c.g.screen_size == 'J') {
  94.         width = 40;
  95.         height = 16;
  96.         }
  97.     else    {
  98.         if (c.g.screen_type == 'B' || c.g.screen_type == 'M')
  99.             height = 25;
  100.         }
  101. #endif
  102.  
  103.     switch (c.g.screen_type) {
  104.  
  105.     case 'V':
  106. #if defined(UNIX)
  107. #if defined(UNIXV)
  108.         return(FALSE);        /* not supported yet */
  109. #else    /* assume Berkeley sockets */
  110.         if (ioctl(0, TIOCGETP, (int)&tty) < 0) return(FALSE);
  111.         savtty = tty;
  112.         tty.sg_flags |= RAW;
  113.         tty.sg_flags &= ~ECHO;
  114.         if (ioctl(0, TIOCSETP, (int)&tty) < 0) return(FALSE);
  115. #endif
  116.             /* set VT100 mode, origin relative, jump scroll */
  117.         if (c.g.screen_type == 'V') T_RawStr("\033<\033[?6h\033[?4l");
  118. #endif
  119.         break;
  120.  
  121. #if defined(UNIX)
  122.     case 'T':
  123.         initscr();
  124.         noecho();
  125.         raw();
  126.         leaveok(stdscr, FALSE);
  127. #if defined(UNIXV)
  128.         if ((savemodes = fcntl(STDIN, F_GETFL, 0)) < 0 ||
  129.              fcntl(STDIN, F_SETFL, savemodes | O_NDELAY) < 0) {
  130.             return(FALSE);
  131.             }
  132. #endif
  133.         break;
  134. #endif
  135.  
  136. #if defined(MSDOS)
  137.     case 'B':
  138.         t_attrib = NORMAL;
  139.         VidCurOn();
  140.         break;
  141.  
  142.     case 'M':
  143.         t_attrib = NORMAL;
  144.         scrnbase = (char huge *)((long)VidInit() << 16);
  145.         scrnptr = scrnbase;
  146.         VidCurOn();
  147.         break;
  148. #endif
  149.         }
  150.     TClrScreen();
  151.     return(TRUE);
  152.     }
  153.  
  154.  
  155. /* ------------------------------------------------------------ */
  156.  
  157. /* Terminate special terminal handling. */
  158.  
  159. void
  160. TFini()
  161.     {
  162.     TForce();
  163.  
  164.     switch (c.g.screen_type) {
  165.  
  166.     case 'V':
  167. #if defined(UNIX)
  168. #if defined(UNIXV)
  169. #else    /* assume Berkeley sockets */
  170.         ioctl(0, TIOCSETP, (int)&savtty);
  171. #endif
  172. #endif
  173.         break;
  174.  
  175. #if defined(UNIX)
  176.     case 'T':
  177. #if defined(UNIXV)
  178.         fcntl(STDIN, F_SETFL, savemodes);
  179. #endif
  180.         mvcur(0, COLS - 1, LINES - 1, 0);
  181.         clrtoeol();
  182.         refresh();
  183.         endwin();
  184.         break;
  185. #endif
  186.  
  187. #if defined(MSDOS)
  188.     case 'B':
  189.         break;
  190.  
  191.     case 'M':
  192.         VidFini();
  193.         break;
  194. #endif
  195.         }
  196.     }
  197.  
  198.  
  199. /* ------------------------------------------------------------ */
  200.  
  201. /* Adjust the column by the horizontal offset. */
  202.  
  203. void
  204. TAdjCol()
  205.     {
  206.     col += offset;
  207.     }
  208.  
  209.  
  210. /* ------------------------------------------------------------ */
  211.  
  212. /* Ring the terminal bell. */
  213.  
  214. void
  215. TBell()
  216.     {
  217.     switch (c.g.screen_type) {
  218.  
  219.     case 'V':
  220.         T_RawChar(BEL);
  221.         break;
  222.  
  223. #if defined(UNIX)
  224.     case 'T':
  225.         break;
  226. #endif
  227.  
  228. #if defined(MSDOS)
  229.     case 'B':
  230.     case 'M':
  231.         VidBell();
  232.         break;
  233. #endif
  234.         }
  235.     }
  236.  
  237.  
  238. /* ------------------------------------------------------------ */
  239.  
  240. /* Clear to the end of the line. */
  241.  
  242. void
  243. TCLEOL()
  244.     {
  245. #if defined(MSDOS)
  246.     int cnt;
  247. #endif
  248.  
  249.     TForce();
  250.     switch (c.g.screen_type) {
  251.  
  252.     case 'V':
  253.         T_RawStr("\033[K");
  254.         break;
  255.  
  256. #if defined(UNIX)
  257.     case 'T':
  258.         clrtoeol();
  259.         break;
  260. #endif
  261.  
  262. #if defined(MSDOS)
  263.     case 'B':
  264.         VidClear(width - col);
  265.         break;
  266.  
  267.     case 'M':
  268.         for (cnt = 0; cnt < width - col; cnt++) {
  269.             *scrnptr++ = SP;
  270.             *scrnptr++ = t_attrib;
  271.             }
  272.         scrnptr -= 2 * (width - col);
  273.         break;
  274. #endif
  275.         }
  276.     }
  277.  
  278.  
  279. /* ------------------------------------------------------------ */
  280.  
  281. /* Clear the entire screen and put the cursor at row,column 0,0. */
  282.  
  283. void
  284. TClrScreen()
  285.     {
  286.     switch (c.g.screen_type) {
  287.  
  288.     case 'V':
  289.         TSetPoint(0,0);
  290.         T_RawStr("\033[2J");
  291.         break;
  292.  
  293. #if defined(UNIX)
  294.     case 'T':
  295.         clear();
  296.         break;
  297. #endif
  298.  
  299. #if defined(MSDOS)
  300.     case 'B':
  301.     case 'M':
  302.         col = 0;
  303.         for (row = 0; row < height; ++row) TCLEOL();
  304.         break;
  305. #endif
  306.         }
  307.     TSetPoint(0, 0);
  308.     }
  309.  
  310.  
  311. /* ------------------------------------------------------------ */
  312.  
  313. /* Force the cursor to be displayed at the current row,column. */
  314.  
  315. void
  316. TForce()
  317.     {
  318. #if defined(MSDOS)
  319.     int amt = col - offset;
  320.  
  321.     if (amt < 0) amt = 0;
  322.     if (amt > width) amt = width;
  323. #endif
  324.     switch (c.g.screen_type) {
  325.  
  326.     case 'V':
  327.         T_RawFlush();
  328.         break;
  329.  
  330. #if defined(UNIX)
  331.     case 'T':
  332.         refresh();
  333.         break;
  334. #endif
  335.  
  336. #if defined(MSDOS)
  337.     case 'B':
  338.         VidCursor(row, amt);
  339.         break;
  340.  
  341.     case 'M':
  342.         scrnptr = scrnbase + line_offsets[row] + 2 * amt;
  343.         VidCursor(row, amt);
  344.         break;
  345. #endif
  346.         }
  347.     }
  348.  
  349.  
  350. /* ------------------------------------------------------------ */
  351.  
  352. /* Return the current cursor column. */
  353.  
  354. int
  355. TGetCol()
  356.     {
  357.     return(col);
  358.     }
  359.  
  360.  
  361. /* ------------------------------------------------------------ */
  362.  
  363. /* Wait for and return the next key. */
  364.  
  365. int
  366. TGetKey()
  367.     {
  368.     int chr;
  369.     char cchr;
  370.  
  371. #if defined(MSDOS)
  372.     if (c.g.key_type == 'S') {
  373.         while (read(3, &cchr, 1) < 1) ;
  374.         return(cchr);
  375.         }
  376.     else    {
  377.         chr = PSystem(0x7) & 0xFF;
  378.         if (chr == 0)
  379.             return(0x100 + (PSystem(0x7) & 0xFF));
  380.         else    return(chr);
  381.         }
  382. #endif
  383. #if defined(UNIX)
  384.  
  385.     if (gotchar != -1) {
  386.         chr = gotchar;
  387.         gotchar = -1;
  388.         return(chr);
  389.         }
  390.  
  391.     switch (c.g.screen_type) {
  392.  
  393.     case 'V':
  394. #if defined(UNIXV)
  395.         return(0);
  396. #else    /* assume Berkeley sockets */
  397.         read(0, &cchr, sizeof(cchr));
  398.         return(cchr & 0xFF);
  399. #endif
  400.         break;
  401.  
  402.     case 'T':
  403. #if defined(UNIXV)
  404.         read(0, &cchr, sizeof(cchr));
  405.         return(cchr & 0xFF);
  406. #else    /* assume Berkeley sockets */
  407.         return(getch() & 0xFF);
  408. #endif
  409.         break;
  410.         }
  411. #endif
  412.     }
  413.  
  414.  
  415. /* ------------------------------------------------------------ */
  416.  
  417. /* Return the horizontal offset. */
  418.  
  419. int
  420. TGetOffset()
  421.     {
  422.     return(offset);
  423.     }
  424.  
  425.  
  426. /* ------------------------------------------------------------ */
  427.  
  428. /* Return the current cursor row. */
  429.  
  430. int
  431. TGetRow()
  432.     {
  433.     return(row);
  434.     }
  435.  
  436.  
  437. /* ------------------------------------------------------------ */
  438.  
  439. /* Return the width of character C as displayed by TPutChar, if C
  440. started in the specified column. */
  441.  
  442. int
  443. TGetWidth(chr, column)
  444.     char chr;
  445.     int column;
  446.     {
  447.     if (c.g.use_caret) {
  448.         if (chr >= SP && chr <= '~')
  449.             return(1);
  450.         else if (chr == TAB)
  451.             return(cbuf->c.tab_spacing -
  452.                 (column % cbuf->c.tab_spacing));
  453.         else if (chr & 0x80)
  454.             return(1 + TGetWidth(chr & 0x7F, column + 1));
  455.         else    return(1 + TGetWidth(chr ^ '@', column + 1));
  456.         }
  457.     else    {
  458.         if (chr != TAB)
  459.             return(1);
  460.         else    return(cbuf->c.tab_spacing -
  461.                 (column % cbuf->c.tab_spacing));
  462.         }
  463.     }
  464.  
  465.  
  466. /* ------------------------------------------------------------ */
  467.  
  468. /* Turn off highlighting. */
  469.  
  470. void
  471. THiOff()
  472.     {
  473.     switch (c.g.screen_type) {
  474.  
  475.     case 'V':
  476.         T_RawStr("\033[0m");
  477.         break;
  478.  
  479. #if defined(UNIX)
  480.     case 'T':
  481.         standend();
  482.         break;
  483. #endif
  484.  
  485. #if defined(MSDOS)
  486.     case 'B':
  487.     case 'M':
  488.         t_attrib = NORMAL;
  489.         break;
  490. #endif
  491.         }
  492.     }
  493.  
  494.  
  495. /* ------------------------------------------------------------ */
  496.  
  497. /* Turn on highlighting. */
  498.  
  499. void
  500. THiOn()
  501.     {
  502.     switch (c.g.screen_type) {
  503.  
  504.     case 'V':
  505.         T_RawStr("\033[7m");
  506.         break;
  507.  
  508. #if defined(UNIX)
  509.     case 'T':
  510.         standout();
  511.         break;
  512. #endif
  513.  
  514. #if defined(MSDOS)
  515.     case 'B':
  516.     case 'M':
  517.         t_attrib = REVERSE;
  518.         break;
  519. #endif
  520.         }
  521.     }
  522.  
  523.  
  524. /* ------------------------------------------------------------ */
  525.  
  526. /* Return 'Y', if a key is available, 'N' if not, or '?' if you can't
  527. tell. */
  528.  
  529. char
  530. TIsKey()
  531.     {
  532. #if defined(MSDOS)
  533.     if (c.g.key_type == 'S')
  534.         return('?');
  535.     else    return(PSystem(0xB) & 0xFF ? 'Y' : 'N');
  536. #endif
  537. #if defined(UNIX)
  538. #if !defined(UNIXV)
  539.     struct timeval timeout;
  540.     fd_set rfd;
  541.     char chr;
  542. #endif
  543.  
  544.     if (gotchar != -1) return('Y');
  545.  
  546.     switch (c.g.screen_type) {
  547.  
  548.     case 'V':
  549. #if defined(UNIXV)
  550.         return('?');
  551. #else    /* assume Berkeley sockets */
  552.  
  553.         FD_ZERO(&rfd);
  554.         FD_SET(0, &rfd);
  555.         timeout.tv_sec = 0;
  556.         timeout.tv_usec = 0;
  557.         if (select(RFDSIZE, &rfd, 0, 0, &timeout) == 1) {
  558.             read(0, &chr, sizeof(chr));
  559.             gotchar = chr & 0xFF;
  560.             return('Y');
  561.             }
  562.         else    {
  563.             return('N');
  564.             }
  565. #endif
  566.         break;
  567.  
  568.     case 'T':
  569. #if defined(UNIXV)
  570.         return('?');
  571. #else    /* assume Berkeley sockets */
  572.  
  573.         FD_ZERO(&rfd);
  574.         FD_SET(0, &rfd);
  575.         timeout.tv_sec = 0;
  576.         timeout.tv_usec = 0;
  577.         if (select(RFDSIZE, &rfd, 0, 0, &timeout) == 1) {
  578.             read(0, &chr, sizeof(chr));
  579.             gotchar = chr & 0xFF;
  580.             return('Y');
  581.             }
  582.         else    {
  583.             return('N');
  584.             }
  585. #endif
  586.         break;
  587.         }
  588. #endif
  589.     }
  590.  
  591.  
  592. /* ------------------------------------------------------------ */
  593.  
  594. /* Return the number of columns in the screen.  */
  595.  
  596. int
  597. TMaxCol()
  598.     {
  599. #if defined(UNIX)
  600.     if (c.g.screen_type == 'T') return(COLS);
  601.     else
  602. #endif
  603.     return(width);
  604.     }
  605.  
  606.  
  607. /* ------------------------------------------------------------ */
  608.  
  609. /* Return the number of rows in the screen.  */
  610.  
  611. int
  612. TMaxRow()
  613.     {
  614. #if defined(UNIX)
  615.     if (c.g.screen_type == 'T') return(LINES);
  616.     else
  617. #endif
  618.     return(height);
  619.     }
  620.  
  621.  
  622. /* ------------------------------------------------------------ */
  623.  
  624. /* Put a printed representation of the specified character in a
  625. buffer.  If BUF is not-NULL, use it (it should be at least
  626. SMALLBUFFSIZE characters).  Otherwise, use a static buffer.  Return a
  627. pointer to the start of the buffer. */
  628.  
  629. char *
  630. TPrintChar(c, buf)
  631.     char c;
  632.     char *buf;
  633.     {
  634.     char *savebuf;
  635.  
  636.     if (buf == NULL) buf = printbuf;
  637.     savebuf = buf;
  638.  
  639.     c &= 0xff;
  640.     if (c & 0x80) {
  641.         *buf++ = '~';
  642.         c &= 0x7f;
  643.         }
  644.  
  645.     if (c < SP || c == DEL) {
  646.         *buf++ = '^';
  647.         c ^= '@';
  648.         }
  649.  
  650.     *buf++ = c;
  651.     *buf = NUL;
  652.     return(savebuf);
  653.     }
  654.  
  655.  
  656. /* ------------------------------------------------------------ */
  657.  
  658. /* Put the character to the screen, expanding tabs and control
  659. characters. */
  660.  
  661. void
  662. TPutChar(chr)
  663.     char chr;
  664.     {
  665.     int cnt;
  666.  
  667.     if (c.g.vis_gray) {
  668.         if (chr == SP) {
  669.             T_RawChar(VIS_SPACE_CHAR);
  670.             ++col;
  671.             return;
  672.             }
  673.         else if (chr == VIS_NL_CHAR) {
  674.             T_RawChar(VIS_NL_CHAR);
  675.             ++col;
  676.             return;
  677.             }
  678.         }
  679.     if (c.g.use_caret) {
  680.         if (chr >= SP && chr <= '~') {
  681.             T_RawChar(chr);
  682.             ++col;
  683.             }
  684.         else if (chr == TAB) {
  685.             cnt = cbuf->c.tab_spacing - (col % cbuf->c.tab_spacing);
  686.             if (c.g.vis_gray) {
  687.                 T_RawChar(VIS_TAB_CHAR);
  688.                 ++col;
  689.                 cnt--;
  690.                 }                
  691.             for ( ; cnt > 0; cnt--, col++) T_RawChar(SP);
  692.             }
  693.         else if (chr & 0x80) {
  694.             TPutChar('~');
  695.             TPutChar(chr & 0x7f);
  696.             }
  697.         else    {
  698.             TPutChar('^');
  699.             TPutChar(chr ^ '@');
  700.             }
  701.         }
  702.     else    {    /* just send it */
  703.         if (chr == TAB) {
  704.             cnt = cbuf->c.tab_spacing - (col % cbuf->c.tab_spacing);
  705.             if (c.g.vis_gray) {
  706.                 T_RawChar(VIS_TAB_CHAR);
  707.                 ++col;
  708.                 cnt--;
  709.                 }                
  710.             for ( ; cnt > 0; cnt--, col++) T_RawChar(SP);
  711.             }
  712.         else    {
  713.             T_RawChar(chr);
  714.             ++col;
  715.             }
  716.         }
  717.     }
  718.  
  719.  
  720. /* ------------------------------------------------------------ */
  721.  
  722. /* Put the string to the screen, expanding each character as TPutChar.
  723. */
  724.  
  725. void
  726. TPutStr(str)
  727.     char *str;
  728.     {
  729.     while (*str != NUL) TPutChar(*str++);
  730.     }
  731.  
  732.  
  733. /* ------------------------------------------------------------ */
  734.  
  735. /* Set the horizontal offset.  Set to 0 means no offset used. */
  736.  
  737. void
  738. TSetOffset(o)
  739.     int o;
  740.     {
  741.     offset = o;
  742.     }
  743.  
  744.  
  745. /* ------------------------------------------------------------ */
  746.  
  747. /* Set the cursor row and column. */
  748.  
  749. void
  750. TSetPoint(xrow, xcol)
  751.     int xrow;
  752.     int xcol;
  753.     {
  754.     char buf[SMALLBUFFSIZE];
  755.  
  756.     if (row == xrow && col == xcol) return;
  757.  
  758.     row = xrow;
  759.     col = xcol;
  760.  
  761.     switch (c.g.screen_type) {
  762.  
  763.     case 'V':
  764.         xsprintf(buf, "\033[%d;%dH", row + 1, col + 1);
  765.         T_RawStr(buf);
  766.         break;
  767.  
  768. #if defined(UNIX)
  769.     case 'T':
  770.         move(row, col);
  771.         break;
  772. #endif
  773.  
  774. #if defined(MSDOS)
  775.     case 'B':
  776.     case 'M':
  777.         TForce();
  778.         break;
  779. #endif
  780.         }
  781.     }
  782.  
  783.  
  784. /* ------------------------------------------------------------ */
  785.  
  786. /* Send the character to the screen, uninterpreted. */
  787.  
  788. void
  789. T_RawChar(chr)
  790.     char chr;
  791.     {
  792.     int amt;
  793.  
  794.     if (offset != 0 && col < offset) return;
  795.     switch (c.g.screen_type) {
  796.  
  797.     case 'V':
  798.         *outptr++ = chr;
  799.         if (outptr >= &outbuf[sizeof(outbuf)]) T_RawFlush();
  800.         break;
  801.  
  802. #if defined(UNIX)
  803.     case 'T':
  804.         addch(chr);
  805.         break;
  806. #endif
  807.  
  808. #if defined(MSDOS)
  809.     case 'B':
  810.         amt = col - offset;
  811.         if (amt < 0) amt = 0;
  812.         if (amt > width) amt = width;
  813.         VidCursor(row, amt);
  814.         VidChar(chr);
  815.         break;
  816.  
  817.     case 'M':
  818.         *scrnptr++ = chr;
  819.         *scrnptr++ = t_attrib;
  820.         break;
  821. #endif
  822.         }
  823.     }
  824.  
  825.  
  826. /* ------------------------------------------------------------ */
  827.  
  828. /* Flush the output buffer. */
  829.  
  830. void
  831. T_RawFlush()
  832.     {
  833.     if (outptr > outbuf) write(1, outbuf, outptr - outbuf);
  834.     outptr = outbuf;
  835.     }
  836.  
  837.  
  838. /* ------------------------------------------------------------ */
  839.  
  840. /* Send the string to the screen, uninterpreted. */
  841.  
  842. void
  843. T_RawStr(str)
  844.     char *str;
  845.     {
  846.     switch (c.g.screen_type) {
  847.  
  848.     case 'V':
  849. #if defined(MSDOS)
  850.     case 'B':
  851.     case 'M':
  852. #endif
  853.         while (*str != NUL) T_RawChar(*str++);
  854.         break;
  855.  
  856. #if defined(UNIX)
  857.     case 'T':
  858.         addstr(str);
  859.         break;
  860. #endif
  861.         }
  862.     }
  863.  
  864.  
  865. /* end of TERM.C -- Terminal Interface Routines */
  866.